package cmd

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"gitee.com/lcc_dr/restful-api-demo/apps"
	"gitee.com/lcc_dr/restful-api-demo/protoctl"

	"gitee.com/lcc_dr/restful-api-demo/conf"

	_ "gitee.com/lcc_dr/restful-api-demo/all"
	"github.com/infraboard/mcube/logger"
	"github.com/infraboard/mcube/logger/zap"
	"github.com/spf13/cobra"
)

var (
	help        bool
	addr        string
	DefaultPath string

	isAtAll bool
	rootCmd = &cobra.Command{
		Use:   "host",
		Short: "host restfule api",
		Long:  "host restfule api",
		RunE: func(cmd *cobra.Command, args []string) error {
			// dingding.DingDingWebhook(addr)

			// zap.DevelopmentSetup()
			/*
				loadGlobalLogger()
				conf.LoadConfigFromToml(DefaultPath)
				g := gin.Default()
			*/
			//使用第三方IOC
			// apps.HostService = impl.NewHostServiceImpl()

			apps.InitImpl()

			// api := protoctl.NewHandleHostService(service)
			// api := protoctl.NewHandleHostService()
			// api.Config()
			loadGlobalLogger()
			// conf.LoadConfigFromToml(DefaultPath)
			manager := NewManager()

			quit := make(chan os.Signal)
			defer close(quit)
			// kill (no param) default send syscall.SIGTERM
			// kill -2 is syscall.SIGINT
			// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
			signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

			go manager.WaitStop(quit)

			return manager.Start()

		},
		PreRunE: func(cmd *cobra.Command, args []string) error {

			//fmt.Println(DefaultPath)
			//fmt.Println(os.Getwd())

			if len(DefaultPath) == 0 {
				home, err := os.Getwd()
				if err != nil {
					log.Fatal(err)
				}
				DefaultPath = home + "/etc/demo.toml"

			}

			err := conf.LoadConfigFromToml(DefaultPath)
			if err != nil {
				log.Fatal(err)
			}
			//fmt.Println(conf.GetConf().At.AtMobiles[0])
			//fmt.Println(conf.GetConf().URL)
			//conf.SetConf(url, atUserIdsrl, atMobiles)

			return nil

		},
	}
)

// Execute executes the root command.
func Execute() error {
	return rootCmd.Execute()
}

type Manager struct {
	l          logger.Logger
	httpServer *protoctl.HttpServer
	grpcServer *protoctl.GrpcServer
	restServer *protoctl.RestServer
}

func (m *Manager) Start() error {

	go m.grpcServer.Start()
	return m.restServer.Start()

	// return m.httpServer.Start()
}
func (m *Manager) WaitStop(quit <-chan os.Signal) {
	for v := range quit {
		switch v {
		default:
			m.l.Infof("received signal: %s", v)
			m.grpcServer.Stop()
			// m.httpServer.Stop()
			m.l.Info("received")
			m.restServer.Stop()
			m.l.Info("received stop")
		}
	}

}

func NewManager() *Manager {
	return &Manager{
		l:          zap.L().Named("manager"),
		httpServer: protoctl.NewHttpServer(),
		grpcServer: protoctl.NewGrpcServer(),
		restServer: protoctl.NewRestServer(),
	}
}

func loadGlobalLogger() error {
	var (
		logInitMsg string
		level      zap.Level
	)
	lc := conf.GetConf().Log
	lv, err := zap.NewLevel(lc.Level)
	if err != nil {
		logInitMsg = fmt.Sprintf("%s, use default level INFO", err)
		level = zap.InfoLevel
	} else {
		level = lv
		logInitMsg = fmt.Sprintf("log level: %s", lv)
	}
	zapConfig := zap.DefaultConfig()
	zapConfig.Level = level
	zapConfig.Files.RotateOnStartup = false
	switch lc.To {
	case conf.ToStdout:
		zapConfig.ToStderr = true
		zapConfig.ToFiles = false
	case conf.ToFile:
		zapConfig.Files.Name = "api.log"
		zapConfig.Files.Path = lc.PathDir
	}
	switch lc.Format {
	case conf.JSONFormat:
		zapConfig.JSON = true
	}
	if err := zap.Configure(zapConfig); err != nil {
		return err
	}
	zap.L().Named("INIT").Info(logInitMsg)
	return nil
}

func init() {

	//f.BoolVarP(&help, "help", "h", false, "打印帮助信息")

	// f.BoolVarP(&version, "version", "v", false, "webhook 版本信息")
	//f.StringVarP(&url, "url", "u", "", "钉钉url")
	//f.StringVarP(&atUserIdsrl, "atUserIds", "U", "", "钉钉发送人")

	rootCmd.PersistentFlags().StringVarP(&DefaultPath, "config", "f", "", " 默认路径为: ./etc/demo.toml")

	//f.BoolVarP(&isAtAll, "isAtAll", "A", false, "@全体人，默认为false")

	// rootCmd.AddCommand(rootCmd)
	// rootCmd.AddCommand(versionCmd)

}
